package com.hodge.core.filter;

import com.hodge.core.enums.ResultCode;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 不同的登陆状态处理
 * Created by 张皓竣 on 2020/9/19
 */
@Slf4j
public class AuthHandler implements
        AuthenticationEntryPoint,
        AccessDeniedHandler,
        AuthenticationFailureHandler,
        AuthenticationSuccessHandler,
        LogoutSuccessHandler {
    /**
     * 未登录
     */
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=utf-8");
        @Cleanup final PrintWriter writer = httpServletResponse.getWriter();
        writer.write(ResultCode.NOT_LOGIN.toResult().toJsonString());
        writer.flush();
    }

    /**
     * 无权限
     */
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=utf-8");
        @Cleanup final PrintWriter writer = httpServletResponse.getWriter();
        writer.write(ResultCode.ACCESS_DENIED.toResult().toJsonString());
        writer.flush();
    }

    /**
     * 登录失败
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        ResultCode code = ResultCode.LOGIN_FALIURE;
        if (e instanceof BadCredentialsException) {
            code = ResultCode.ERROR_PASSWORD;
        } else if (e instanceof LockedException) {
            code = ResultCode.LOCKED_ACCOUNT;
        } else if (e instanceof UsernameNotFoundException) {
            code = ResultCode.UNKNOWN_ACCOUNT;
        }
//        e.printStackTrace();
        httpServletResponse.setContentType("application/json;charset=utf-8");
        @Cleanup final PrintWriter writer = httpServletResponse.getWriter();
        writer.write(code.toResult().toJsonString());
        writer.flush();
    }

    /**
     * 登录成功
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=utf-8");
        @Cleanup final PrintWriter writer = httpServletResponse.getWriter();
        writer.write(ResultCode.SUCCESS.toResult().toJsonString());
        writer.flush();
    }

    /**
     * 注销成功
     */
    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=utf-8");
        @Cleanup final PrintWriter writer = httpServletResponse.getWriter();
        writer.write(ResultCode.SUCCESS.toResult().toJsonString());
        writer.flush();
    }
}
